package com.example.demo.util;

import com.example.demo.dao.DakaCountDao;
import com.example.demo.dao.DakamingxiDao;

import com.example.demo.entity.DakaCount;
import com.example.demo.entity.Dakamingxi;

import com.example.demo.finalUtils.FinalUtils;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.example.demo.finalUtils.Config.*;
import static com.example.demo.util.DateUtil.*;

@Component
public class LoginAuthUtil {
    @Autowired
    FinalUtils finalUtils;
    @Value("${net.tenantName}")
    private  String tenantName;
    @Value("${net.tenantPwd}")
    private  String tenantPwd;
    @Value("${net.host}")
    private  String host;
    @Value("${net.port}")
    private String port;
    @Resource
    private DakaCountDao dakaCountDao;
    @Autowired
    private  RedisUtil redisUtil;
    private static final Logger LOG = LoggerFactory.getLogger(LoginAuthUtil.class);

    public Map<String,List<Dakamingxi>> redis() throws ParseException, IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        Map<String,List<Dakamingxi>> dtoList=new HashMap<>();//返回数据
        String timeStamp = timeStamp();//当前时间戳
        String lastQueryTime="";//时间戳格式
        String lastQueryTimeString="";//日期格式
        long minu=0;//相差分钟
        String date1="";//记录日期
        String date2="";//当前日期
        //设置POST的URL,Header和超时时间,获取token_id
        String postTokenUrl = "https://" + host + ":" + port + POST_TOKEN_URL;
        //设置GET的URL,Header和超时时间（注意tokenId需要加入）,获取站点信息
        String getSitesUrl = "https://" + host + ":" + port + GET_SITES_URL;
        lastQueryTime=redisUtil.get("lastQueryTime").toString();//取缓存中的上次访问时间
        String timeStamps=redisUtil.get("timeStamp").toString();//取缓存中的上次访问时间
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date=  new Date(simpleDateFormat.parse(DateUtil.timeStamp2Date(timeStamps,"yyyy-MM-dd HH:mm:ss")).getTime()-1200000);
        String fugai=DateUtil.dateToStrLong(date);
        fugai=date2TimeStamp(fugai,"yyyy-MM-dd HH:mm:ss");

        if (!lastQueryTime.isEmpty()){//lastQueryTime存在
            lastQueryTimeString = timeStamp2Date(lastQueryTime, "");
            minu= getDateMinu(lastQueryTimeString,timeStamp2Date(timeStamp,""));
            date1=timeStamp4Date(timeStamp);
            date2=timeStamp4Date(lastQueryTime);
            if (minu<10)
            {
                if (date1.equals(date2)){//同一天
                    return dtoList;
                }else {
                    //不是同一天
                    return redisTest(fugai,timeStamp,minu) ;
                }

            }else {//大于10分钟
                return redisTest(fugai,timeStamp,minu) ;
            }

        }else {
           // return dakamingxiList(postTokenUrl,getSitesUrl);

        }
        return null;
    }

    /**
     * redis数据库中，key为lastQueryTime的数据被清空，则需要手动设置一下
     * getUrl1中的  endtime，适当取值
     * @param postTokenUrl
     * @param getSitesUrl
     * @return
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     * @throws IOException
     * @throws ParseException
     */
    public List<Dakamingxi> dakamingxiList (String postTokenUrl,String getSitesUrl) throws KeyStoreException,
        NoSuchAlgorithmException, KeyManagementException, IOException, ParseException
{

        List<Dakamingxi> dtoList=new ArrayList<>();//返回数据
        int count=0;//技术发起通信次数
        String timeStamp = timeStamp();//当前时间戳
        LocalDate localDate=LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");//获得当前日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date=initDateByDay();//当前日期的零点
        String startTime= date2TimeStamp(sdf.format(date),"yyyy-MM-dd HH:mm:ss") ; //当天日期的零点
        String startQueryRowKey=""; //起始索引
        //设置HTTPS忽略证书校验
        SSLContextBuilder builder = new SSLContextBuilder();

        builder.loadTrustMaterial(null, (X509Certificate[] x509Certificates, String s) -> true);

        SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
                builder.build(), new String[]{"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"}
                , null, NoopHostnameVerifier.INSTANCE);
        Registry<ConnectionSocketFactory> registry = RegistryBuilder
                .<ConnectionSocketFactory>create()
                .register("http", new PlainConnectionSocketFactory())
                .register("https", socketFactory).build();
        HttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(registry);

        //设置POST的URL,Header和超时时间
        HttpPost postToken = new HttpPost(postTokenUrl);
        postToken.setHeader("Content-Type", "application/json");
        postToken.setHeader("Accept", "application/json");
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(10 * 1000).setConnectionRequestTimeout(10 * 1000)
                .setSocketTimeout(10 * 1000).setRedirectsEnabled(true).build();
        postToken.setConfig(requestConfig);
        //设置POST的json内容(用户名密码)
        JSONObject jsonObject = new JSONObject();
        jsonObject.put(USERNAME, tenantName);
        jsonObject.put(PASSWORD, tenantPwd);
        String json = jsonObject.toString();
        StringEntity jsonEntity = new StringEntity(json);
        postToken.setEntity(jsonEntity);
        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpResponse postResponse = httpclient.execute(postToken);
        count++;
        if (HttpStatus.SC_OK == postResponse.getStatusLine().getStatusCode()) {
            HttpEntity entity = postResponse.getEntity();
            if (entity != null)
            {
                //发起Post请求并解析出token_id
                JSONObject jsonResponse = new JSONObject(EntityUtils.toString(entity));
                token_id = jsonResponse.getJSONObject("data").getString("token_id");
            }
        }
        //设置GET的URL,Header和超时时间（注意tokenId需要加入）
        HttpGet getSites = new HttpGet(getSitesUrl);
        getSites.setHeader("Content-Type", "application/json");
        getSites.setHeader("Accept", "application/json");
        getSites.setHeader("X-AUTH-TOKEN", token_id);
        getSites.setConfig(requestConfig);
        //发起Get请求并展示结果
        HttpResponse getResponse = httpclient.execute(getSites);
        String getUserUrl1="";
        if (HttpStatus.SC_OK == getResponse.getStatusLine().getStatusCode()) {
            HttpEntity entity = getResponse.getEntity();
            if (entity != null)
            {
                // 解析返回数据
                String stringResponse = EntityUtils.toString(entity);
                JSONObject jsonResponse = new JSONObject(stringResponse);
                JSONArray jsonArray = jsonResponse.getJSONArray("data");
                JSONArray jsonArray1 = new JSONArray();
                List<Dakamingxi> list = new ArrayList<>();
                for (int i = 0; i < jsonArray.length(); i++)
                {
                    JSONObject jsonObject1 = jsonArray.getJSONObject(i);
                    System.out.println("demo==" + jsonObject1.get("id"));
                    getUserUrl1 = "https://" + host + ":" + port +
                            "/controller/campus/v1/oamservice/devicelog?pageSize=200&siteId="
                            + jsonObject1.get("id")
                            + "&beginTime=" + startTime+ "&endTime="
                            + "1586835030"  + "&sceneName=1&startQueryRowKey=" + startQueryRowKey; //获取设备日志上报信息的api
                    HttpGet getUserUrl = new HttpGet(getUserUrl1);
                    getUserUrl.setHeader("Content-Type", "application/json");
                    getUserUrl.setHeader("Accept", "application/json");
                    getUserUrl.setHeader("X-AUTH-TOKEN", token_id);
                    getUserUrl.setConfig(requestConfig);
                    HttpResponse getResponse1 = null;
                    String nextRowkey = "";
                    while (true) {
                        //发起Get请求并展示结果
                        getResponse1 = httpclient.execute(getUserUrl);
                        if (HttpStatus.SC_OK == getResponse1.getStatusLine().getStatusCode()) {
                            HttpEntity entity1 = getResponse1.getEntity();
                            if (entity1 != null) {
                                stringResponse = EntityUtils.toString(entity1);
                                jsonResponse = new JSONObject(stringResponse);
                                JSONObject jsonArrays = jsonResponse.getJSONObject("data");
                                jsonArray1 = jsonArrays.getJSONArray("deviceLog");
                                nextRowkey = jsonArrays.getString("nextRowkey").toString();

                                for (int j = 0; j < jsonArray1.length(); j++) {
                                    String detail = jsonArray1.getJSONObject(j).get("detail").toString();
                                    if (detail.contains("[WLAN_STA_INFO_AP_ASSOCIATE]")) {
                                        Dakamingxi dakamingxis=new Dakamingxi();
                                        // 该信息包含 则为一个新的对象 并放入集合中
                                        dakamingxis.setSiteid(jsonObject1.get("id").toString());
                                        dakamingxis.setSitename(jsonObject1.get("name").toString());
                                        dakamingxis.setMac(jsonArray1.getJSONObject(j).get("stationMac").toString());
                                        dakamingxis.setFirsttime(jsonArray1.getJSONObject(j).get("time").toString());
                                        dakamingxis.setSwtime(jsonArray1.getJSONObject(j).get("time").toString());
                                        dakamingxis.setAccount(jsonArray1.getJSONObject(j).get("stationMac").toString().trim().replace("-", ""));
                                        dakamingxis.setDate(sf.parse(localDate.format(formatter)));
                                        list.add(dakamingxis);
                                    }
                                }
                                if (!nextRowkey.equals("")) {
                                    //下次访问的起始索引
                                    startQueryRowKey = nextRowkey;
                                } else {
                                    //跳出循环
                                    break;
                                }
                            }
                        }

                    }

                 //   addDakaCount(count);
                }

                Map<String, List<Dakamingxi>> collect = list.stream().collect(Collectors.groupingBy(Dakamingxi::getMac));
                //内部遍历 比较，获取最早的打卡时间
                collect.entrySet().forEach(entry ->
                {
                    List<Dakamingxi> dakamingxiList = entry.getValue();
                    Optional<Dakamingxi> dakamingxi = dakamingxiList.stream()
                            .sorted(Comparator.comparing(Dakamingxi::getFirsttime))
                            .collect(Collectors.toList()).stream().findFirst();
                    dtoList.add(dakamingxi.get()); //放入集合中
                });
            }
        }
        httpclient.close();
        redisUtil.set("lastQueryTime","1586835030");
        //结束连接
    return dtoList;
}

    /**
     * redis中key为lastQueryTime的数据存在
     * @param timeStamp
     * @param minu
     * @return
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     * @throws IOException
     * @throws ParseException
     */
  public  Map<String,List<Dakamingxi>> redisTest(String beginTime ,String timeStamp,long minu) throws KeyStoreException,
          NoSuchAlgorithmException, KeyManagementException, IOException, ParseException {
        List<Dakamingxi> dtoList=new ArrayList<>();
        List<Dakamingxi> dtoList1=new ArrayList<>();
        String startQueryRowKey=""; //起始索引
        LocalDate localDate=LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        System.out.println(beginTime);

        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");//获得当前日期
        Date date=initDateByDay();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String startTime= date2TimeStamp(sdf.format(date),"yyyy-MM-dd HH:mm:ss") ;
        String date1="";
        String date2="";
        int count=0;
        //设置HTTPS忽略证书校验
        SSLContextBuilder builder = new SSLContextBuilder();

        builder.loadTrustMaterial(null, (X509Certificate[] x509Certificates, String s) -> true);

        SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
                builder.build(), new String[]{"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"}
                , null, NoopHostnameVerifier.INSTANCE);
        Registry<ConnectionSocketFactory> registry = RegistryBuilder
                .<ConnectionSocketFactory>create()
                .register("http", new PlainConnectionSocketFactory())
                .register("https", socketFactory).build();
        HttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(registry);

        //设置POST的URL,Header和超时时间
        String postTokenUrl = "https://" + host + ":" + port + POST_TOKEN_URL;
        HttpPost postToken = new HttpPost(postTokenUrl);
        postToken.setHeader("Content-Type", "application/json");
        postToken.setHeader("Accept", "application/json");
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(10 * 1000).setConnectionRequestTimeout(10 * 1000)
                .setSocketTimeout(10 * 1000).setRedirectsEnabled(true).build();
        postToken.setConfig(requestConfig);
        //设置POST的json内容(用户名密码)
        JSONObject jsonObject = new JSONObject();
        jsonObject.put(USERNAME, tenantName);
        jsonObject.put(PASSWORD, tenantPwd);
        String json = jsonObject.toString();
        StringEntity jsonEntity = new StringEntity(json);
        postToken.setEntity(jsonEntity);
        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpResponse postResponse = httpclient.execute(postToken);
        count++;
        if (HttpStatus.SC_OK == postResponse.getStatusLine().getStatusCode()) {
            HttpEntity entity = postResponse.getEntity();
            if (entity != null) {
                //发起Post请求并解析出token_id
                JSONObject jsonResponse = new JSONObject(EntityUtils.toString(entity));
                token_id = jsonResponse.getJSONObject("data").getString("token_id");
            }
        }
        //设置GET的URL,Header和超时时间（注意tokenId需要加入）
        String getSitesUrl = "https://" + host + ":" + port + GET_SITES_URL;
        HttpGet getSites = new HttpGet(getSitesUrl);
        getSites.setHeader("Content-Type", "application/json");
        getSites.setHeader("Accept", "application/json");
        getSites.setHeader("X-AUTH-TOKEN", token_id);
        getSites.setConfig(requestConfig);
        //发起Get请求并展示结果
        HttpResponse getResponse = httpclient.execute(getSites);
        if (HttpStatus.SC_OK == getResponse.getStatusLine().getStatusCode()) {
            HttpEntity entity = getResponse.getEntity();
            if (entity != null) {
                // 解析返回数据
                String stringResponse = EntityUtils.toString(entity);
                JSONObject jsonResponse = new JSONObject(stringResponse);
                JSONArray jsonArray = jsonResponse.getJSONArray("data");
                JSONArray jsonArray1 = new JSONArray();
                List<Dakamingxi> list = new ArrayList<>();
                List<Dakamingxi> list1 = new ArrayList<>();
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject jsonObject1 = jsonArray.getJSONObject(i);
                    System.out.println("demo======" + jsonObject1.get("id"));
                    String getUserUrl1 = "";
                    String lastQueryTime = redisUtil.get("lastQueryTime").toString();//取redis数据
                    if (lastQueryTime != null) {
                        date1 = timeStamp4Date(timeStamp);
                        date2 = timeStamp4Date(lastQueryTime);
                        if (!date1.equals(date2)) {//不是同一天
                            getUserUrl1 = "https://" + host + ":" + port +
                                    "/controller/campus/v1/oamservice/devicelog?pageSize=200&siteId=" + jsonObject1.get("id")
                                    + "&beginTime=" + startTime + "&endTime="
                                    + timeStamp + "&sceneName=1&startQueryRowKey=" + startQueryRowKey; //获取设备日志上报信息的api

                        }else {//同一天
                            getUserUrl1 = "https://" + host + ":" + port +
                                    "/controller/campus/v1/oamservice/devicelog?pageSize=200&siteId=" + jsonObject1.get("id")
                                    + "&beginTime=" + lastQueryTime + "&endTime="
                                    + timeStamp + "&sceneName=1&startQueryRowKey=" + startQueryRowKey; //获取设备日志上报信息的api
                        }
                    }


                    HttpGet getUserUrl = new HttpGet(getUserUrl1);
                    getUserUrl.setHeader("Content-Type", "application/json");
                    getUserUrl.setHeader("Accept", "application/json");
                    getUserUrl.setHeader("X-AUTH-TOKEN", token_id);
                    getUserUrl.setConfig(requestConfig);
                    HttpResponse getResponse1 = null;
                    String nextRowkey = "";
                    while (true) {
                        //发起Get请求并展示结果
                        getResponse1 = httpclient.execute(getUserUrl);
                        if (HttpStatus.SC_OK == getResponse1.getStatusLine().getStatusCode()) {
                            HttpEntity entity1 = getResponse1.getEntity();
                            if (entity1 != null) {
                                stringResponse = EntityUtils.toString(entity1);
                                jsonResponse = new JSONObject(stringResponse);
                                JSONObject jsonArrays = jsonResponse.getJSONObject("data");
                                jsonArray1 = jsonArrays.getJSONArray("deviceLog");
                                nextRowkey = jsonArrays.getString("nextRowkey").toString();
                                for (int j = 0; j < jsonArray1.length(); j++) {
                                    String detail = jsonArray1.getJSONObject(j).get("detail").toString();
                                    if (detail.contains("[WLAN_STA_INFO_AP_ASSOCIATE]")) {
                                        Dakamingxi dakamingxis=new Dakamingxi();
                                        // 该信息包含 则为一个新的对象 并放入集合中
                                        dakamingxis.setSiteid(jsonObject1.get("id").toString());
                                        dakamingxis.setSitename(jsonObject1.get("name").toString());
                                        dakamingxis.setMac(jsonArray1.getJSONObject(j).get("stationMac").toString());
                                        dakamingxis.setFirsttime(jsonArray1.getJSONObject(j).get("time").toString());
                                        dakamingxis.setSwtime(jsonArray1.getJSONObject(j).get("time").toString());
                                        dakamingxis.setAccount(jsonArray1.getJSONObject(j).get("stationMac").toString().trim().replace("-", ""));
                                        dakamingxis.setDate(sf.parse(localDate.format(formatter)));
                                        list.add(dakamingxis);
                                    }else if(detail.contains("WLAN_LOG_STA_ONLINEFAIL_OR_OFFLINE_INFO")){
                                        Dakamingxi dakamingxis=new Dakamingxi();
                                        // 该信息包含 则为一个新的对象 并放入集合中
                                        dakamingxis.setSiteid(jsonObject1.get("id").toString());
                                        dakamingxis.setSitename(jsonObject1.get("name").toString());
                                        dakamingxis.setMac(jsonArray1.getJSONObject(j).get("stationMac").toString());
                                        dakamingxis.setEwtime(jsonArray1.getJSONObject(j).get("time").toString());
                                        dakamingxis.setEndtime(jsonArray1.getJSONObject(j).get("time").toString());
                                        dakamingxis.setAccount(jsonArray1.getJSONObject(j).get("stationMac").toString().trim().replace("-", ""));
                                        dakamingxis.setDate(sf.parse(localDate.format(formatter)));
                                        list1.add(dakamingxis);
                                    }
                                }
                                if (!nextRowkey.equals("")) {
                                    //下次访问的起始索引
                                    startQueryRowKey = nextRowkey;
                                } else {
                                    //跳出循环
                                    break;
                                }
                            }
                        }

                    }


                }
                //新增打卡统计数据
                addDakaCount(count);
                Map<String, List<Dakamingxi>> collect1 = list1.stream().collect(Collectors.groupingBy(Dakamingxi::getMac));//根据mac分组
                collect1.entrySet().forEach(entry ->
                {
                    List<Dakamingxi> dakamingxiList = entry.getValue();
                    Optional<Dakamingxi> dakamingxi = dakamingxiList.stream()
                            .sorted(Comparator.comparing(Dakamingxi::getEndtime).reversed())
                            .collect(Collectors.toList()).stream().findFirst();
                    dtoList1.add(dakamingxi.get()); //放入集合中
                });

                Map<String, List<Dakamingxi>> collect = list.stream().collect(Collectors.groupingBy(Dakamingxi::getMac));//根据mac分组
                //内部遍历 比较，获取最早的打卡时间
                collect.entrySet().forEach(entry ->
                {
                    List<Dakamingxi> dakamingxiList = entry.getValue();
                    Optional<Dakamingxi> dakamingxi = dakamingxiList.stream()
                            .sorted(Comparator.comparing(Dakamingxi::getFirsttime))
                            .collect(Collectors.toList()).stream().findFirst();
                    dtoList.add(dakamingxi.get()); //放入集合中
                });
            }
        }
        httpclient.close();//结束连接
        redisUtil.set("lastQueryTime",timeStamp);
        Map<String,List<Dakamingxi>> map=new HashMap<String,List<Dakamingxi>>();
        map.put("dtoList",dtoList);
        map.put("dtoList1",dtoList1);
       return null;
}

    /**
     * 统计打卡数据
     * @param count
     */
   public void addDakaCount(int count){
       LocalDate localDate=LocalDate.now();
       DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");//获得当前日期
       DakaCount dakaCount = dakaCountDao.count(new Date());
       if(dakaCount==null){
           dakaCount= new DakaCount();
           dakaCount.setApp(0);
           dakaCount.setCjsj(localDate.format(formatter));
           dakaCount.setFwcs(0);
           dakaCount.setTxcs(1);
           dakaCountDao.insert(dakaCount);
       }else{
           dakaCount.setTxcs(dakaCount.getTxcs()+count);
           dakaCountDao.update(dakaCount);
       }
    }
}

